﻿using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Sitecore.Data.Items;
using Workflow.Alerts.DAL;
using workflow.Dal;
using System.Data.Objects;
using System.ServiceModel;
using Workflow.Alerts.Utils;

namespace Workflow.Alerts
{
    public class SummaryDetailsViewPresenter : Presenter
    {
        #region members

        private readonly AlertViewDAL model;
        private readonly ISummaryDetailsView view;

        #endregion

        #region constructor
        public SummaryDetailsViewPresenter(ISummaryDetailsView _view)
            : this(_view, null)
        { }

        public SummaryDetailsViewPresenter(ISummaryDetailsView _view, ISessionProvider session)
            : base(_view, session)
        {
            view = base.GetView<ISummaryDetailsView>();
            view.OnSummaryLoad += view_OnPageLoad;
            view.OnSummaryAddRemarks += view_AddNewComments;
            view.OnSummaryUpdateRemarks += view_UpdateComments;
            view.OnSummaryChangeActualArea += view_OnChangeActualArea;
            view.OnSummaryChangeActualStartDate += view_OnChangeActualStartDate;
            view.OnSummaryChangeActualEndDate += view_OnChangeActualEndDate;
            view.OnSummaryChangeContractor += view_OnChangeContractor;
            view.OnSummaryChangeActivityType += view_OnChangeActivityType;
            view.OnSummaryUpdateTrafficComments += view_UpdateTrafficComments;
            view.OnSummarySaveTrafficComment += view_AddNewTrafficComments;
            view.OnSummaryHasTrafficProblemsChanged += view_HasTrafficProblemsChanged;
            view.OnPriceUpdated += view_OnPriceUpdated;
            model = new AlertViewDAL();
        }
        #endregion

        #region private methods

        private void view_OnPageLoad()
        {
            WorkflowFilterSql filterSql = GetWorkflowFilter();
            //view.ContractorNameList = model.GetContractors(filterSql);
            BindSummaryFields(filterSql);

        }

        private void BindSummaryFields(WorkflowFilterSql filterSql)
        {
            EstateDataSet.SummaryDetailsDataTable summaryTable = model.GetAlertSummaryDetails(filterSql);
            if (summaryTable.Rows.Count == 1)
            {
                EstateDataSet.SummaryDetailsRow summary = summaryTable[0];
                view.ActualArea = string.IsNullOrEmpty(summary.actualarea) ? (Nullable<Int16>)alertDetails.EstimateArea : (Nullable<Int16>)Int16.Parse(summary.actualarea);
                if (!string.IsNullOrEmpty(summary.actualstartdate))
                    view.ActualStartDate = DateTime.Parse(summary.actualstartdate);
                else
                    view.ActualStartDate = alertDetails.EstimateStartDate;
                if (!string.IsNullOrEmpty(summary.actualenddate))
                    view.ActualEndDate = DateTime.Parse(summary.actualenddate);
                else
                    view.ActualEndDate = alertDetails.EstimateEndDate;

                view.ActivityTypes = WorkflowEnums.ActivityTypeList;
                view.ActivityType = alertDetails.ActivityType;
                


                


                using (WorkflowEntitySet context = new WorkflowEntitySet())
                {
                    var alert = context.Alert.Include("AlertMaterials").Where(a => a.id == view.AlertId).First();
                    view.HasTrafficProblems = alert.trafficproblems;
                    view.TrafficComments = GetTrafficComments(context);
                    view.Comments = GetComments(context);
                    alert.MunicipalityReference.Load();
                    var contractors= context.Contractor.Where(c => context.municipality_contractor.Where(mc => mc.municipalityId == alert.Municipality.id && mc.contractorId == c.id).Any()).ToList();
                    Dictionary<int, string> dicContractors = new Dictionary<int, string>();
                    foreach (var c in contractors)
                    {
                        dicContractors.Add(c.id, c.name);
                    }
                    dicContractors.Add(0, "none");

                    view.ContractorNameList = dicContractors;

                    view.ContractorId = string.IsNullOrEmpty(summary.coid) ? null : (Nullable<Int32>)Int32.Parse(summary.coid);
                    view.ContractorEmail = summary.coemail;
                    view.ContractorContactPerson = summary.coperson;
                    view.ContractorPhone = summary.cophone;

                    var materialsSum = alert.AlertMaterials.Sum(am => am.price);
                    if (materialsSum > 0)
                        view.MaterialsSum = String.Format("{0:0.00}", materialsSum);

                    if (CurrentUser.Type == WorkflowEnums.UserType.NetworkOperator)
                    {
                        
                        alert.Municipality.PersonReference.Load();
                        view.NetworkOperatorAddress = string.Format("{0}, {1}, {2}", alert.Municipality.postcity,
                                                                                    alert.Municipality.postaddress,
                                                                                    alert.Municipality.postcode);
                        view.NetworkOperatorEmail = alert.Municipality.Person.email;
                        view.NetworkOperatorContactPerson = string.Format("{0} {1}", alert.Municipality.Person.firstname, alert.Municipality.Person.lastname);
                        view.NetworkOperatorContactPhone = alert.Municipality.Person.Phone1;
                    }
                    else
                    {
                        if (!alert.NetworkOperatorReference.IsLoaded)
                            alert.NetworkOperatorReference.Load();
                        alert.ContactNetworkUserReference.Load();


                        view.NetworkOperatorAddress = string.Format("{0}, {1}, {2}", alert.NetworkOperator.postcity,
                                                                                    alert.NetworkOperator.postaddress,
                                                                                    alert.NetworkOperator.postcode);
                        view.NetworkOperatorEmail = alert.ContactNetworkUser.email;
                        view.NetworkOperatorContactPerson = string.Format("{0} {1}", alert.ContactNetworkUser.firstname, alert.ContactNetworkUser.lastname); ;
                        view.NetworkOperatorContactPhone = alert.ContactNetworkUser.Phone1;
                    }

                }

            }
        }

        private void view_OnChangeActualArea()
        {
            var filter = new WorkflowFilter()
            {
                AlertId = view.AlertId,
                AlertArea = view.ActualArea
            };
            model.UpdateAlertActualData(new WorkflowFilterSql(filter), null);
        }

        private void view_OnChangeActualStartDate()
        {
            var filter = new WorkflowFilter()
            {
                AlertId = view.AlertId,
                StartDate = view.ActualStartDate
            };
            model.UpdateAlertActualData(new WorkflowFilterSql(filter), null);
        }

        private void view_OnChangeActualEndDate()
        {
            var filter = new WorkflowFilter()
            {
                AlertId = view.AlertId,
                EndDate = view.ActualEndDate
            };
            model.UpdateAlertActualData(new WorkflowFilterSql(filter), null);
        }

        private void view_OnChangeContractor()
        {
            var filter = new WorkflowFilter()
            {
                AlertId = view.AlertId,
                ContractorId = view.ContractorId
            };
            var filterSql = new WorkflowFilterSql(filter);
            model.UpdateContractor(filterSql);
            ContractorDAL cdal = new ContractorDAL();
            EstateDataSet.ContractorDataTable contractors = cdal.GetContractorDetails(filterSql);
            if (contractors != null && contractors.Rows.Count == 1)
            {
                var contractor = contractors[0];
                view.ContractorPhone = contractor.phone1;
                view.ContractorEmail = contractor.email;
                view.ContractorContactPerson = string.Format("{0} {1}", contractor.firstname, contractor.lastname);
            }
            else
            {
                view.ContractorPhone = string.Empty;
                view.ContractorEmail = string.Empty;
                view.ContractorContactPerson = string.Empty;
            }
        }

        private void view_OnPriceUpdated()
        {
            using (WorkflowEntitySet context = new WorkflowEntitySet())
            {
                var alert = context.Alert.Include("AlertMaterials").Where(a => a.id == view.AlertId).First();
                var materialsSum = alert.AlertMaterials.Sum(am => am.price);
                if (materialsSum > 0)
                    view.MaterialsSum = String.Format("{0:0.00}", materialsSum);
                else
                    view.MaterialsSum = "0.0";

                bool isherstel = alert.AlertMaterials.Where(am => am.uitstel == true).Any();
                view.IsHerstel = isherstel;
            }
        }

        private WorkflowFilterSql GetWorkflowFilter()
        {
            WorkflowFilter filter = new WorkflowFilter
            {
                AlertId = view.AlertId,
                Comments = view.Comment,
                UserId = CurrentUser.Id,
                ContractorId = view.ContractorId

            };
            if (alertDetails != null)
                filter.MunicipalityId = alertDetails.MunicipalityId;

            return new WorkflowFilterSql(filter);
        }
     
        private void view_OnChangeActivityType()
        {
            using (WorkflowEntitySet context = new WorkflowEntitySet())
            {
                var alert = context.Alert.Where(a => a.id == view.AlertId).First();
                int oldAcativityType = alert.activitytype;
                if (oldAcativityType != view.ActivityType)
                {

                    alert.activitytype = view.ActivityType;
                    context.SaveChanges();


                    Notification.SendActivityChangedNotification(alert, WorkflowEnums.ActivityTypeList[oldAcativityType]);
                }
            }
        }     

        #region Traffic problems activity

        private void view_UpdateTrafficComments(string text, int id)
        {
            using (WorkflowEntitySet context = new WorkflowEntitySet())
            {
                var comment = context.TrafficComments.Where(tc => tc.id == id).First();

                comment.comment = text;
                comment.updatedatetime = DateTime.Now;
                context.SaveChanges();

                var alert = context.Alert.Where(a => a.id == view.AlertId).First();

                Notification.SendTrafficCommentsChangedNotification(alert, text, CurrentUser);
                view.TrafficComments = GetTrafficComments(context);
            }
        }

        private void view_AddNewTrafficComments()
        {
            using (WorkflowEntitySet context = new WorkflowEntitySet())
            {
                TrafficComments tccomment = new TrafficComments()
                {
                    comment = view.TrafficComment,
                    Person = context.Person.Where(p => p.id == CurrentUser.Id).First(),
                    Alert = context.Alert.Where(a => a.id == view.AlertId).First(),
                    createddatetime = DateTime.Now
                };

                context.AddToTrafficComments(tccomment);
                context.SaveChanges();
                var alert = context.Alert.Where(a => a.id == view.AlertId).First();
                Notification.SendTrafficCommentsChangedNotification(alert, view.TrafficComment, CurrentUser);
                view.TrafficComments = GetTrafficComments(context);
            }
        }

        private EstateDataSet.RemarksDataTable GetTrafficComments(WorkflowEntitySet context)
        {
            var aler = context.Alert.Include("TrafficComments").Where(a => a.id == view.AlertId).First();


            var comments = aler.TrafficComments.ToList<TrafficComments>();

            var commentstable = new EstateDataSet.RemarksDataTable();
            foreach (var comment in comments)
            {
                comment.PersonReference.Load();
                var newrow = commentstable.NewRemarksRow();
                newrow.comments = comment.comment;
                newrow.date = (comment.updatedatetime ?? comment.createddatetime).ToString();
                newrow.id = comment.id;
                newrow.name = string.Format("{0} {1}", comment.Person.firstname, comment.Person.lastname);
                newrow.userid = comment.Person.id;
                newrow.organizationname = comment.Person.organizationname;
                commentstable.Rows.Add(newrow);
            }

            return commentstable;

        }

        private void view_HasTrafficProblemsChanged()
        {
            using (WorkflowEntitySet context = new WorkflowEntitySet())
            {
                var alert = context.Alert.Where(a => a.id == view.AlertId).First();
                alert.trafficproblems = view.HasTrafficProblems;

                context.SaveChanges();
            }
        }

        #endregion


        #region Comments activity

        private void view_UpdateComments(string text, int id)
        {
            using (WorkflowEntitySet context = new WorkflowEntitySet())
            {
                var comment = context.Comments.Where(tc => tc.id == id).First();

                comment.comment = text;
                comment.updatedatetime = DateTime.Now;
                context.SaveChanges();

                var alert = context.Alert.Where(a => a.id == view.AlertId).First();

                Notification.SendTrafficCommentsChangedNotification(alert, text, CurrentUser);
                view.Comments = GetComments(context);
            }
        }

        private void view_AddNewComments()
        {
            using (WorkflowEntitySet context = new WorkflowEntitySet())
            {
                Comments tccomment = new Comments()
                {
                    comment = view.Comment,
                    Person = context.Person.Where(p => p.id == CurrentUser.Id).First(),
                    Alert = context.Alert.Where(a => a.id == view.AlertId).First(),
                    createddatetime = DateTime.Now
                };

                context.AddToComments(tccomment);
                context.SaveChanges();
                var alert = context.Alert.Where(a => a.id == view.AlertId).First();
                Notification.SendTrafficCommentsChangedNotification(alert, view.Comment, CurrentUser);
                view.Comments = GetComments(context);
            }
        }

        private EstateDataSet.RemarksDataTable GetComments(WorkflowEntitySet context)
        {
            var aler = context.Alert.Include("Comments1").Where(a => a.id == view.AlertId).First();

            var comments = aler.Comments1.ToList<Comments>();

            var commentstable = new EstateDataSet.RemarksDataTable();
            foreach (var comment in comments)
            {
                comment.PersonReference.Load();
                var newrow = commentstable.NewRemarksRow();
                newrow.comments = comment.comment;
                newrow.date = (comment.updatedatetime ?? comment.createddatetime).ToString();
                newrow.id = comment.id;
                newrow.name = string.Format("{0} {1}", comment.Person.firstname, comment.Person.lastname);
                newrow.userid = comment.Person.id;
                newrow.organizationname = comment.Person.organizationname;
                commentstable.Rows.Add(newrow);
            }

            return commentstable;
        }

        #endregion

        #endregion

        protected AlertDetails alertDetails
        {
            get
            {
                return Session[WorkflowConstants.ExecuteData] as AlertDetails;
            }
            set
            {
                Session[WorkflowConstants.ExecuteData] = value;
            }
        }
    }
}
